using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

namespace ThaiLanguageTools
{
    // Immutable
    public class QueryInfo
    {
        // How to choose to replace a rule in the dictionary? This is very important.
        // What if words are the same and masks are different? Ok, we reject the formation,
        // but does it matter whether which mask we take up? The one with higher probability
        // (i.e. shorter formation sequence?). What if probabilities are the same? Just pick
        // the first one? Does this lead to a loop?

        public readonly String Text;
        
        /// <summary>
        /// Replacement mask for rules applied, e.g. if s->t rule was applied to "sasa", to
        /// form text "tasa", the mask would be "#asa". Mask always has the same length as the
        /// text. Searches for source are always done on the Mask instead of Text, so we avoid
        /// duplicate rule application to same token (and thus infinite loops)
        /// </summary>
        public readonly String Mask;
        public readonly decimal Probability;

        public QueryInfo(String text) : this(text, text, 1) { }

        public QueryInfo(String text, String mask, decimal probability)
        {
            Debug.Assert(probability > 0 && probability <= 1);
            Debug.Assert(!String.IsNullOrEmpty(text));
            Debug.Assert(!String.IsNullOrEmpty(mask));
            Debug.Assert(text.Length == mask.Length);

            Text = text;
            Mask = mask;
            Probability = probability;
        }

        /// <summary>
        /// Replace the rule.Src with rule.Dst once in this query, and return the resulting query.
        /// Returns null if the replacement cannot be made.
        /// </summary>
        /// <param name="startIndex"></param>
        /// <param name="rule"></param>
        /// <returns></returns>
        public QueryInfo ReplaceOnce(ref int index, ChangeRule rule)
        {
            index = Mask.IndexOf(rule.Src, index);
            if (index < 0) { return null; }

            String newText = Text.Substring(0, index) + rule.Dest + Text.Substring(index + rule.Src.Length);
            String newMask = Mask.Substring(0, index) + rule.DestMask + Mask.Substring(index + rule.Src.Length);
            decimal newProb = Probability * rule.Probability;
            index += rule.Src.Length;

            return new QueryInfo(newText, newMask, newProb);
        }

        public override string ToString()
        {
            return String.Format("{0}|{1} ({2})", Text, Mask, Probability);
        }
    }
}
